/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package Wires.impl;

import java.io.File;
import java.net.URL;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.m2m.atl.engine.AtlLauncher;
import org.eclipse.m2m.atl.engine.vm.nativelib.ASMOclAny;

import Wires.ConnectableElement;
import Wires.InputActualParameter;
import Wires.OutputActualParameter;
import Wires.Query;
import Wires.WiresPackage;
import Wires.exep.QueryFailedException;
import Wires.exep.ResourceNotFoundException;
import Wires.exep.TypeNotFoundException;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Query</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * </p>
 *
 * @generated
 */
public class QueryImpl extends TransformationImpl implements Query {
	/***************************************************/
	/***************** Modifications *******************/
	
	public void execute(ConnectableElement incoming) throws Exception{
		
		List<InputActualParameter> inparam = this.getInParams();
	
		boolean ready = true;
		for (InputActualParameter parameter : inparam){
			ready = ready && ((InputActualParameterImpl)parameter).getActive();
		}
		
		if (super.getActive() == true && ready){			
			if (this.getType() == null)
				throw new TypeNotFoundException(this);
			
			String transformationPath = this.getType().getPath();
			File f = new File(transformationPath);			
			if (this.getType().getPath() == null || this.getType().getPath().equals("") || !f.exists())
				throw new ResourceNotFoundException(this.getType());
			
			
			//Compile Atl, if necessary			
			transformationPath = super.compileAtl(transformationPath);

			File transformationFile = null;
			try {
				transformationFile = new File(transformationPath);
			} catch (Exception e) {
				throw new ResourceNotFoundException(this.getType());
			}
			URL transformationResource = transformationFile.toURI().toURL();
			
			Map<String, Object> models = super.getInputsMap();
										 
			//Load libraries
			Map<String, URL> libMap = super.getLibMap();
			
			//Execute transformation
			ASMOclAny res = (ASMOclAny)AtlLauncher.getDefault().launch(transformationResource, libMap,
					models, Collections.EMPTY_MAP, Collections.EMPTY_LIST, Collections.EMPTY_MAP);
			
			if (res == null)
				throw new QueryFailedException(this);
			
			//Save the result in the output parameter
			for (OutputActualParameter parameter : this.getOutParams()){
				((OutputActualParameterImpl)parameter).setBasicDataValue(res);
			}

			//Get the output parameters
			List<ConnectableElement> outParamlist = new LinkedList<ConnectableElement>();
			for (OutputActualParameter oap : this.getOutParams()){
				outParamlist.add(((ConnectableElement)oap));
			}
			
			for (InputActualParameter iap : this.getInParams()){
				((InputActualParameterImpl) iap).setActive(false);
			}
			
			if (this.getControlNode()!=null)
				super.setActive(false);
			
			//Call the main method from WiresSpecification
			WiresSpecificationImpl.execute(outParamlist, null);			
		}
	}
	
	/**************** Modifications End ****************/
	/***************************************************/
	
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected QueryImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return WiresPackage.Literals.QUERY;
	}

} //QueryImpl
